EC2インスタンスの価格表を生成するPythonスクリプトを作成しました
EC2の価格表を生成する必要があったので、その際のコードを公開します。以下をPythonで実装した感じです。
実行環境
- Python 2.7.10
Pythonスクリプト
東京リージョンのオンデマンド価格のみ必要であったため、それ以外の情報は破棄しています。
# coding: utf-8 import json import re import sys import datetime import urllib2 def __get_price_list(url): response = urllib2.urlopen(url) # 最終行のcallbackしているJavaScript行を取得する callback_line = response.readlines()[-1] # callback処理の文字列を除去する js_string = callback_line[len('callback('):-len(');')] # JSONに変換するためkey部分に""を付ける p = re.compile(r'([0-9a-zA-Z]*):') json_string = p.sub((lambda m:'"' + m.group(1) + '":'), js_string) price_json = json.loads(json_string) # key: region:operating_system:instance_type, value: price のdictに変換する prices = {} for price_per_region in price_json['config']['regions']: region = price_per_region['region'] if region != 'ap-northeast-1': continue for instance_family in price_per_region['instanceTypes']: for instance_size in instance_family['sizes']: instance_type = instance_size['size'] for value_column in instance_size['valueColumns']: operating_system = value_column['name'] price = value_column['prices']['USD'] # priceが N/A の場合はリストに追加しない if price == 'N/A': continue prices[region + ':' + operating_system + ':' + instance_type] = price return prices def main(argv): price_list = { 'created': str(datetime.datetime.now()), 'prices': {} } prices = price_list['prices'] # 旧世代 prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/linux-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/rhel-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/sles-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswin-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswinSQL-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswinSQLWeb-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswinSQLEnterprise-od.min.js')) # 現行世代 prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/rhel-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/sles-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswin-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswinSQL-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswinSQLWeb-od.min.js')) prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswinSQLEnterprise-od.min.js')) print json.dumps(price_list, sort_keys=True, indent=4) if __name__ == "__main__": main(sys.argv)
出力結果は以下のようになります。diffが取りやすいようにKeyでソートしてあります。
{ "created": "2017-07-11 20:11:55.347102", "prices": { "ap-northeast-1:linux:c1.medium": "0.158", "ap-northeast-1:linux:c1.xlarge": "0.632", ... "ap-northeast-1:sles:x1.16xlarge": "9.771", "ap-northeast-1:sles:x1.32xlarge": "19.441" } }
Price List APIを使わないのは?
ドキュメントにも記載がある通り料金ページの方が正となっているためです。
AWS Price List API は料金詳細を参考としてのみ提供します。オファーファイルとサービスの料金ページの間に不一致がある場合、AWS はサービスの料金ページに表示されている料金を請求します。
AWS Price List API の使用 - AWS 請求情報とコスト管理
最後に
CLI上でコマンドをパイプでつなげてワンライナーでやるのはスマートな感じがしますが、ちょっと加工したい場合はPythonのようなスクリプトでやる方が簡単ですよね。参考になれば幸いです。